package edu.ustb.efws.pipeline.collect.handler;

import edu.ustb.efws.base.domain.Position;
import edu.ustb.efws.monitor.service.DetectorMonitorService;
import edu.ustb.efws.pipeline.collect.cache.MaxICacheService;
import edu.ustb.efws.pipeline.collect.cache.RiskCache;
import edu.ustb.efws.pipeline.collect.cache.ThosCache;
import edu.ustb.efws.pipeline.domain.IptLog;
import edu.ustb.efws.pipeline.domain.RiskLog;
import edu.ustb.efws.pipeline.domain.Thos;
import edu.ustb.efws.pipeline.service.RiskLogService;
import edu.ustb.efws.utils.SafeMath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * ipt设备风险值处理
 *
 * @author TS Group
 */
class IptRiskLogHandler extends RiskLogHandler<IptLog> {
    private final MaxICacheService maxICacheService;
    private final DetectorMonitorService detectorMonitorService;

    IptRiskLogHandler(List<Position> positions, RiskLogService riskLogService,
                      MaxICacheService maxICacheService, DetectorMonitorService detectorMonitorService) {

        super(positions, riskLogService);
        this.maxICacheService = maxICacheService;
        this.detectorMonitorService = detectorMonitorService;
    }

    @Override
    protected Map<Integer, Position> filterMonitorPositions(List<Position> positions) {
        return positions.stream()
                .filter(e -> e.getIptId() != 41)
                .collect(Collectors.toMap(Position::getIptId, e -> e));
    }

    @Override
    protected Position getPosition(Map<Integer, Position> monitorPositions, IptLog iptLog) {
        return monitorPositions.get(iptLog.getDetectorId());
    }

    @Override
    protected boolean isDetectorActive(Position position) {
        boolean active = detectorMonitorService.isActive(position.getThoId());
        if (!active){
            RiskCache.INSTANCE.remove(position.getId());
        }
        return active;
    }

    @Override
    protected RiskLog buildLog(Position position, IptLog t){
        RiskLog log = new RiskLog();
        log.setPositionId(position.getId());
        log.setMonth(t.getMonth());
        log.setI(t.getMaxI());
        log.setU(t.getMaxU());
        log.setP(t.getP());
        log.setIptTime(t.getCollectTime());

        Optional<Thos> thosOpt = ThosCache.INSTANCE.getOpt(position.getThoId());
        if(thosOpt.isPresent()){
            Thos thos  = thosOpt.get();
            log.setH(thos.getH());
            log.setO(thos.getO());
            log.setT(thos.getT());
            log.setThosTime(thos.getTime());
        }else{
            log.setH(0f);
            log.setO(0f);
            log.setT(0f);
            log.setThosTime(t.getCollectTime());
        }

        float maxI =getMaxI(t);
        log.setMaxI(maxI);

        float[] score = SafeMath.riskScore(log.getI(), log.getU(), maxI, log.getT(), log.getH());
        log.setRiskType((int)score[0]);
        log.setScore(format(score[1]));
        log.setRiskGrade(SafeMath.riskGrade(score[1]));

        RiskCache.INSTANCE.put(log);

        return log;
    }

    private float format(float f){
        return (Math.round(f * 100) * 1.0f)/100;
    }

    private float getMaxI(IptLog t){
        return maxICacheService.getOpt(t.getDetectorId()).orElseGet(t::getMaxI);
    }
}
